<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link rel="stylesheet" href="../style/journal.css" type="text/css" />
<style type="text/css"><!--
.googleadsense {
	margin: 2px;
	padding: 0px;
//--></style><script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-65008-1";
urchinTracker();
</script><title>我对 Catalyst 的理解和介绍</title>
</head>
<body>
<a href="index.html">Journal</a>(2005) | <a href="../blog/"><b>Blog</b></a>(2006) | <a href="http://www.fayland.org/cgi-bin/random_link.pl">RandomLink</a> | <a href="AboutFayland.html">WhoAmI</a> | <a href="LiveBookmark.html">LiveBookmark</a> | <a href="http://www.fayland.org/">HomePage</a>
<p><&lt;Previous: <a href="Catalyst_NoFavIcon.html">Catalyst && favicon.ico</a>&nbsp;&nbsp;>>Next: <a href="051009_practice.html">Practice</a></p>
<h1>我对 Catalyst 的理解和介绍</h1>
<div class='content'>
<p>Category: <a href='Catalyst.html'>Catalyst</a> &nbsp; Keywords: <b>Catalyst</b></p>昨晚跟 <a href="http://www.livejournal.com/users/joe_jiang/">joe jiang</a>, Qiang 和 <a href="http://www.wanghui.org">cnhackTNT</a> 讨论了下成立 <a href="http://dev.catalyst.perl.org">Catalyst</a> 学习小组的事。Qiang 还建了个 <a href='http://www.livejournal.com/community/perlchina/'>Livejournal</a> 的 journal. 打算把大家的学习过程之中学到的经验或经历共享下。如果能对初学者有所帮助就再好不过。<br />因为我也算接触 Catalyst 比较久了，所以打算讲点对它的理解。一家之言，如有错误请批评指正。兴之所致而讲，如不连贯也见谅。<p />Catalyst 是对最近颇为流行的 MVC 模型或者说是 Ruby on rails 在 Perl 上的实现。在我看来，Perl 其实功能啥都不缺，就缺一组合。而 Catalyst 就是一个快速 Web 开发的漂亮组合拳。<p />M - Model, 一般用来将数据库对象化，这样能比较容易访问和操作。Perl 中最有名的就是 <a href="http://search.cpan.org/perldoc?Class::DBI">Class::DBI</a><br />V - View, 就是视图，用来处理界面显示。Perl 中比较有名的是 Template-Toolkit 和 Mason<br />C - Controller, 就是控制器。就是针对不同的 action 或 request, 来执行不同的代码。另外有个名词就是分发/Dispatch<p />Catalyst 中可以使用很多不同的 Model 和 View/Template. 看个人喜好而定，我一般偏向于使用最流行的 CDBI 和 <a href="http://www.template-toolkit.org">TT</a>.<br />Class::DBI 和 TT 本来在 Perl 世界中就很出名。而按一般逻辑思维，视图与模型搞定后就剩下事件处理了。Catalyst 无缝地整合了这两者，而事件处理/Controller 则让我赞不绝口。<p />首先从目录结构上来说（运行 catalyst MyApp），略过某些东西：<br /><pre>created "MyApp" # 整一目录<br />created "MyApp\lib"<br />created "MyApp\root" # 可以将一些静态文件放在这如 CSS/Gif/JS etc.<br />created "MyApp\lib\MyApp"<br />created "MyApp\lib\MyApp\M" # 这里就是放置 Model <br />created "MyApp\lib\MyApp\V" # 一般也就一个文件 TT.pm<br />created "MyApp\lib\MyApp\C" # 这里比较重要，所有的 Controller 都放这<br />created "MyApp\lib\MyApp.pm" # 主程序模块<br />created "MyApp/Build.PL" # 可以用来打包发布模块<br />created "MyApp\script" # 脚本目录<br />created "MyApp\script/myapp_cgi.pl" # 普通 CGI 环境下运行<br />created "MyApp\script/myapp_fastcgi.pl" # FastCGI<br />created "MyApp\script/myapp_server.pl" # 这个就是我们一般写代码要运行的脚本<br />created "MyApp\script/myapp_test.pl"<br />created "MyApp\script/myapp_create.pl" # 这个用来创建新的 C/M/V 模块</pre>对 Controller 来讲，Catalyst 实行 URL-to-Action.<br />在服务器运行时它将检查 MyApp.pm 和 \M \V \C 这三目录下的所有模块文件。对于 \C 目录下模块文件中实行 URL-Action 匹配。比如我们在 \C 下有一新文件 List.pm （用 perl script/myapp_create.pl controller List 创建）。List.pm 中如果这么写：<br /><pre>sub list : Global { # 这个 Action 自动对应类如 http://fayland:3000/list 这样的 URL<p />sub view : Regexp('^tag/(.*)') { # 这个对应类如 http://fayland:3000/tag/Catalyst 这样的 URL<p />sub orderby : Local { # 这个对应 http://fayland:3000/list/orderby 这样的 URL<br />                        与 Global 不同的是它在 URL 中多了个模块名</pre>还有其他后缀。这是个非常棒的东西。这样你就不用在一个文件中写哪个模块对应哪个子程序了（以前要用类如 <a href="http://search.cpan.org/perldoc?CGI::Application">CGI::Application</a> 完成这功能）。很方便。<p />一般而言，把简单的 \V 和 \M 搞完后（真的很简单，里面一般一个文件十行代码就可以），剩下来的就是 Controller 的编写了。<br />Controller 一般子程序的第一行是 my ( $self, $c ) = @_;<br />这里就是引进了一个最重要的 $c, 其实你不必理会它是什么东西（其实是模块的一个实例），只需要知道项目里的所有东西你都可以从这得到。需要什么，找它就是。它又分为很多部件，包括 request, response, stash, config, forward 等。<p />request 包含你请求（浏览器对服务器的请求）时的所有信息。如 cookies, 参数/params 和其他头/header 信息。可以通过 my $value = $c->req->params->{'foo'}; 当你访问 http://fayland:3000/?foo=bar 时， $value 就是 bar 了。<p />response 就是服务器对浏览器的反馈。你对浏览器的输出等就是靠这个部件来解决。$c->res->output('Congratulations, NewApp is on Catalyst!'); 一般很少用 output, 因为输出一般用 Template 解决。<p />config 一般存储项目的配置文件。我一般用 YAML 来配置，然后通过 YAML::LoadFile 来导入该配置文件<p />forward 这个是很有用的东西。一般用来实现在子程序间的跳转。<p />stash 所有子程序传递到 TT 模块中的变量都是用这个变量来传递。（用过 TT 的人都应该知道的）<h3>代码片断</h3><pre>package Eplanet::C::Add;<p />use base 'Catalyst::Base';<p />sub add : Global {<br /> &nbsp; &nbsp;my ( $self, $c ) = @_;<br /> &nbsp; &nbsp;$c->stash->{cates} = [ Eplanet::M::CDBI::Category->retrieve_all ];<br />}</pre>Eplanet::M::CDBI::Category 这就是对象化后的数据库。retrieve_all 是 CDBI 的一个函数。就是获得所有数据。然后将其放到 $c->stash->{cates} 里，这样模块文件就能访问这数据了。<br /><pre># add.tt 模版文件<br />&lt;select name="cms_cat_id"><br />[% FOREACH cate IN cates -%]<br />&lt;option value="[% cate.cat_id %]">[% cate.cat_name %]<br />[% END -%]<br />&lt;/select></pre>这样就是一个最基本的完整的过程。http://fayland:3000/add 实现 URL-Action, Eplanet::M::CDBI::Category 是数据库，然后通过 $c->stash 传递到模版里。一般的流程就是这样。<p />学习流程一般这样：<p />* 看 <a href="http://search.cpan.org/perldoc?Catalyst::Manual::Intro">Catalyst::Manual::Intro</a><br />* svn co http://dev.catalyst.perl.org/repos/Catalyst/trunk 里看那文件夹里的 examples<br />* 订阅 <a href="http://lists.rawmode.org/mailman/listinfo/catalyst">http://lists.rawmode.org/mailman/listinfo/catalyst</a><br />* 写代码，做试验，问问题<p />Enjoy Catalyst.</div>
<p><&lt;Previous: <a href="Catalyst_NoFavIcon.html">Catalyst && favicon.ico</a>&nbsp;&nbsp;>>Next: <a href="051009_practice.html">Practice</a></p>
<p><strong>Options:</strong> <a href='http://del.icio.us/post?title=%E6%88%91%E5%AF%B9%20Catalyst%20%E7%9A%84%E7%90%86%E8%A7%A3%E5%92%8C%E4%BB%8B%E7%BB%8D&url=http://www.fayland.org/journal/Catalyst_Overview.html'>+Del.icio.us</a></p>
<strong>Related items</strong>
<ul><li><a href='050328.html'>Catalyst & Eplanet</a> < <span class='digit'>2005-03-28 13:19:19</span> ></li><li><a href='050423.html'>Day [05.4.23] stay with me</a> < <span class='digit'>2005-04-23 16:17:02</span> ></li><li><a href='Catalyst_Authenticate.html'>Catalyst Authenticate</a> < <span class='digit'>2005-09-26 12:50:39</span> ></li><li><a href='Catalyst_Flaw.html'>Catalyst 的一个不足（一个已去掉）</a> < <span class='digit'>2005-09-27 13:44:31</span> ></li><li><a href='Catalyst_Session_Win32.html'>Catalyst 在 Win32 下的 Session</a> < <span class='digit'>2005-09-29 11:08:04</span> ></li><li><a href='Catalyst_NoFavIcon.html'>Catalyst && favicon.ico</a> < <span class='digit'>2005-09-30 00:57:57</span> ></li><li><a href='Catalyst_XMLRPC.html'>Catalyst && XML-RPC</a> < <span class='digit'>2005-10-11 21:50:30</span> ></li><li><a href='Catalyst_YAML.html'>Catalyst config YAML</a> < <span class='digit'>2005-12-10 12:50:39</span> ></li><li><a href='CatalystAdventCalendar_CN.html'>Catalyst Advent Calendar 中文版</a> < <span class='digit'>2005-12-15 23:28:40</span> ></li></ul>
Created on <span class="digit">2005-10-08 01:39:40</span>, Last modified on <span class="digit">2005-10-08 02:15:13</span><br />
Copyright 2004-2005 All Rights Reserved. Powered by <a href="Eplanet.html">Eplanet</a> && <a href='http://catalyst.perl.org'>Catalyst</a> 5.62.
</body>
</html>